**********************************************************************************************************
* Do-file to replicate analyses in 'Does Ideology Trump Geography? Political Divides and MEP Responses to Democratic Backsliding'
* November 2025
**********************************************************************************************************

*+++++++++++++++++++++++++++++++PREAMBLE+++++++++++++++++++++++++++++++++++++* 

cd "" // Set path to directory where replication package was unzipped

*******************
* ADOs
*******************
ssc install heatplot, replace
ssc install palettes, replace
ssc install colrspace, replace
ssc install cleanplots, replace

*-------------------------------------------------------------------------------
* ANALYSES IN THE MAIN TEXT
*-------------------------------------------------------------------------------

*Figure 1: A heatmap of position-taking in EP debates on democratic backsliding
clear all
use "replication dataset_1.dta"
drop if MEP_time==0
gen EPG_debate_cluster= EPG*1000+ Debate
revrs Anti
recode revAnti (1=0) (2=1)
collapse (mean) pro_eu_percentage = revAnti, by(memberstate Debate)
encode memberstate , gen(country)
set scheme cleanplots
heatplot pro_eu_percentage i.country i.Debate, ramp(subtitle("Share Pro-EU", pos(11))) title("Share of MEPs pro-EU Intervention") xtitle("Debate number") ytitle("Member State")    xlabel(1(1)18, angle(45))

*Table 1 
clear all
use "replication dataset_1.dta"
drop if MEP_time==0
revrs Anti
recode revAnti (1=0) (2=1)
gen speak=0 if revA==.
replace speak=1 if revA!=.
gen EP8=1 if term==8
replace EP8=0 if term==7
*Selection equation
gllamm speak CEE new_demo_el_evol eu_position2 galtan2 RRP gov Debate_own_MS LIBE EPG_role EP8 Age duration_corr, i(EPG id_number) link(probit) family(binomial) adapt
esttab, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic scalars(ll)
predict xbhat, xb
gen mills = normalden(xbhat) / normal(xbhat)
*Outcome equation - model 1
melogit revAnti i.CEE new_demo_el_evol eu_position2 galtan2 RRP gov Debate_own_MS LIBE i.term mills if Removable_recoded !=1 || EPG: , or
esttab, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic
*Outcome equation - model 2
melogit revAnti i.CEE##c.new_demo_el_evol eu_position2 galtan2 RRP i.CEE##i.gov Debate_own_MS LIBE i.term mills if Removable_recoded !=1 || EPG:, or
esttab, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic

*Figure 2: A heatmap of position-taking in EP roll-call votes on democratic backsliding
use "replication dataset_2.dta", clear
logit Anti_populist_agenda CEE term if type_vote==4 & excluded_votes==0  & subst!=2, cluster (EPG_vote_cluster) or
collapse (mean) pro_eu_percentage = Anti_populist_agenda if e(sample)==1, by(memberstate vote_id)
encode memberstate , gen(country)
set scheme cleanplots
heatplot pro_eu_percentage i.country i.vote, ramp(subtitle("Share Pro-EU", pos(11))) title("Share of MEPs pro-EU Intervention") xtitle("Roll-call vote number")    ytitle("Member State")    xlabel(1(1)17, angle(45))

*Table 2
use "replication dataset_2.dta", clear
melogit Anti_populist_agenda CEE eu_position2 galtan2 RRP gov Debate_own_MS new_demo_el_evol i.vote_id if type_vote==4 & excluded_votes==0 & subst!=2 || EPG: || id_number:, or
esttab, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic scalars(ll)
estimates store model_1
melogit Anti_populist_agenda i.CEE##c.new_demo_el_evol eu_position2 galtan2 RRP i.CEE##i.gov Debate_own_MS i.vote_id if type_vote==4 & excluded_votes==0 & subst!=2 || EPG: || id_number:, or
estimates store model_2
esttab model_1 model_2, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic scalars(ll)
use "replication dataset_1.dta"
drop if MEP_time==0
gen EPG_debate_cluster= EPG*1000+ Debate
merge 1:m id_number RCV using "replication dataset_2.dta"
gen Debate_pos=1 if Anti==.
replace Debate_pos=2 if Anti==0
replace Debate_pos=3 if Anti==1
replace Debate_pos=. if _merge!=3
melogit Anti_populist_agenda CEE eu_position2 galtan2 RRP i.Debate_pos gov Debate_own_MS new_demo_el_evol i.vote_id if type_vote==4 & excluded_votes==0 & subst!=2 || EPG: || id_number:, or 
estimates store model_3
melogit Anti_populist_agenda i.CEE##c.new_demo_el_evol eu_position2 galtan2 RRP i.Debate_pos i.CEE##i.gov Debate_own_MS i.vote_id if type_vote==4 & excluded_votes==0 & subst!=2 || EPG: || id_number:, or
estimates store model_4
esttab model_3 model_4, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic scalars(ll)

*Figure 3 
*It is based on model 4 above, hence no need to load another dataset
melogit Anti_populist_agenda i.CEE##c.new_demo_el_evol eu_position2 galtan2 RRP i.Debate_pos i.CEE##i.gov Debate_own_MS i.vote_id if type_vote==4 & excluded_votes==0 & subst!=2 || EPG: || id_number:, or
margins CEE, at(new_demo_el_evol = (0 .2 .4 .6 .8 1))
marginsplot, level(90) recast(line) yscale(range(0 (.2) 1)) ylabel(0(.2)1, grid) legend(order(1 "CEE = 0" 2 "CEE = 1")) title("Interaction: CEE × Democratic erosion") ytitle("Probability of voting against democratic backsliding") xtitle("Democratic erosion")

*Figure 4 
*Again, it is based on model 4 above, hence no need to load another dataset
melogit Anti_populist_agenda i.CEE##c.new_demo_el_evol eu_position2 galtan2 RRP i.Debate_pos i.CEE##i.gov Debate_own_MS i.vote_id if type_vote==4 & excluded_votes==0 & subst!=2 || EPG: || id_number:, or
esttab, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic scalars(ll)
margins CEE, at(gov = (0 1))
marginsplot, level(90) yscale(range(0 (.2) 1)) ylabel(0(.2)1, grid) legend(order(1 "CEE = 0" 2 "CEE = 1")) title("Interaction: CEE × Government party") ytitle("Probability of voting against democratic backsliding") xtitle("Government party")


*-------------------------------------------------------------------------------
* ADDITIONAL ANALYSES IN THE APPENDIX
*-------------------------------------------------------------------------------

*Table A2
*Models 1 and 2
use "replication dataset_2.dta", clear
gllamm Anti_pop_three CEE eu_position2 galtan2 RRP gov Debate_own_MS new_demo_el_evol, b(0) i(EPG id_number) link(mlogit) eform
esttab, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic scalars(ll)
gen CEE_erosion=CEE*new_demo_el_evol
gen CEE_gov=CEE*gov
gllamm Anti_pop_three CEE eu_position2 galtan2 RRP gov Debate_own_MS new_demo_el_evol CEE_erosion CEE_gov, b(0) i(EPG id_number) link(mlogit) eform
esttab, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic scalars(ll)
*Models 3 and 4
use "replication dataset_1.dta", clear 
drop if MEP_time==0
gen EPG_debate_cluster= EPG*1000+ Debate
merge 1:m id_number RCV using "replication dataset_2.dta""
gen Debate_pos=1 if Anti==.
replace Debate_pos=2 if Anti==0
replace Debate_pos=3 if Anti==1
replace Debate_pos=. if _merge!=3
tab Debate_pos, gen (Spoke_)
gllamm Anti_pop_three CEE eu_position2 galtan2 RRP gov Debate_own_MS new_demo_el_evol Spoke_2 Spoke_3, b(0) i(EPG id_number) link(mlogit) eform
esttab, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic scalars(ll)
gen CEE_erosion=CEE*new_demo_el_evol
gen CEE_gov=CEE*gov
gllamm Anti_pop_three CEE eu_position2 galtan2 RRP gov Debate_own_MS new_demo_el_evol CEE_erosion CEE_gov Spoke_2 Spoke_3, b(0) i(EPG id_number) link(mlogit) eform
esttab, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic scalars(ll)

*Table A3
use "replication dataset_1.dta", clear 
drop if MEP_time==0
gen EPG_debate_cluster= EPG*1000+ Debate
merge 1:m id_number RCV using "replication dataset_2.dta"
revrs Anti
gen Diff_beh=1 if revAnti==1 & Anti_populist_agenda==1
replace Diff_beh=1 if revAnti==2 & Anti_populist_agenda==0
recode Diff_beh (.=0) if revAnti==1 & Anti_populist_agenda==0
recode Diff_beh (.=0) if revAnti==2 & Anti_populist_agenda==1
gen Diff_beh2=Diff_beh
replace Diff_beh2=1 if subst==2 & revAnti!=.

logit Diff_beh CEE eu_position2 galtan2 RRP gov Debate_own_MS Loyal_EPG i.term EPG_role Age, or
estimates store model_1
logit Diff_beh2 CEE eu_position2 galtan2 RRP gov Debate_own_MS Loyal_EPG i.term EPG_role Age, or
estimates store model_2
esttab model_1 model_2, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic

*Table A4
clear all
use "replication dataset_1.dta"
drop if MEP_time==0
revrs Anti
recode revAnti (1=0) (2=1)
gen speak=0 if revA==.
replace speak=1 if revA!=.
gen EP8=1 if term==8
replace EP8=0 if term==7
gllamm speak CEE new_demo_el_evol Auth_legacy eu_position2 galtan2 RRP gov Debate_own_MS LIBE EPG_role EP8 Age duration_corr, i(EPG id_number) link(probit) family(binomial) adapt
esttab, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic
predict xbhat, xb
gen mills = normalden(xbhat) / normal(xbhat)
melogit revAnti Auth_legacy i.CEE new_demo_el_evol eu_position2 galtan2 RRP gov Debate_own_MS LIBE i.term mills if Removable_recoded !=1 || EPG: , or
estimates store model_1
melogit revAnti Auth_legacy i.CEE##c.new_demo_el_evol eu_position2 galtan2 RRP i.CEE##i.gov Debate_own_MS LIBE i.term mills if Removable_recoded !=1 || EPG:, or
estimates store model_2
esttab model_1 model_2, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic scalars(ll)

*Table A5
use "replication dataset_2.dta", clear
melogit Anti_populist_agenda CEE Auth_legacy eu_position2 galtan2 RRP gov Debate_own_MS new_demo_el_evol i.vote_id if type_vote==4 & excluded_votes==0 & subst!=2 || EPG: || id_number:, or
estimates store model_1
melogit Anti_populist_agenda i.CEE##c.new_demo_el_evol Auth_legacy eu_position2 galtan2 RRP i.CEE##i.gov Debate_own_MS i.vote_id if type_vote==4 & excluded_votes==0 & subst!=2 || EPG: || id_number:, or
estimates store model_2
esttab model_1 model_2, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic scalars(ll)
use "replication dataset_1.dta", clear 
drop if MEP_time==0
gen EPG_debate_cluster= EPG*1000+ Debate
merge 1:m id_number RCV using "replication dataset_2.dta"
gen Debate_pos=1 if Anti==.
replace Debate_pos=2 if Anti==0
replace Debate_pos=3 if Anti==1
replace Debate_pos=. if _merge!=3
melogit Anti_populist_agenda CEE eu_position2 galtan2 RRP i.Debate_pos gov Debate_own_MS new_demo_el_evol i.vote_id if type_vote==4 & excluded_votes==0 & subst!=2 || EPG: || id_number:, or
melogit Anti_populist_agenda CEE Auth_legacy eu_position2 galtan2 RRP i.Debate_pos gov Debate_own_MS new_demo_el_evol i.vote_id if type_vote==4 & excluded_votes==0 & subst!=2 || EPG: || id_number:, or
estimates store model_3
melogit Anti_populist_agenda i.CEE##c.new_demo_el_evol Auth_legacy eu_position2 galtan2 RRP i.Debate_pos i.CEE##i.gov Debate_own_MS i.vote_id if type_vote==4 & excluded_votes==0 & subst!=2 || EPG: || id_number:, or
estimates store model_4
esttab model_3 model_4, eform  star(* 0.10 ** 0.05 *** 0.01)  b(a2) se(a2) pr2 aic bic scalars(ll)